package bb.lanxing.calc.fixer;

import android.location.Location;
import android.text.TextUtils;

import bb.lanxing.App;
import bb.lanxing.calc.calculator.GeoidHeightCalc;
import bb.lanxing.manager.SystemSensorManager;
import bb.lanxing.util.Log;

public class AltitudeCalibrator {
    final private static String TAG = "AltitudeCalibrator";
    final private static int GPS_ALTITUDE_SAMPLE_MAX = 8;
    private int altitudeAdjustValue;
    private int altitudeSource;
    private boolean isPressureValid = false;
    private final GeoidHeightCalc geoidHeightCalc = new GeoidHeightCalc();
    private LocationDataItem locDataItem = new LocationDataItem();
    private double altitude_offset = 0.0d;//based on GPS altitude

    public void updateConfigs(int vAltitudeSource, int vAltitudeOffset) {
        altitudeSource = vAltitudeSource;
        altitudeAdjustValue = vAltitudeOffset;
        isPressureValid = SystemSensorManager.getInstance().hasPressureSensor(App.getContext());
    }

    public void process(Location location) {
        float f = 0.0f;
        Log.v(TAG, "process: altitudeSource=" + altitudeSource
                + ",altitudeAdjustValue=" + altitudeAdjustValue + ",isPressureValid=" + isPressureValid);

        //altitude from GPS
        if (altitudeSource == 0) {
            if (location.getExtras() != null) {
                String string = location.getExtras().getString("GEOIDHEIGHT");
                if (!TextUtils.isEmpty(string)) {
                    try {
                        f = Float.parseFloat(string);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (f == 0.0f) {
                        f = geoidHeightCalc.adjust(location.getLatitude(), location.getLongitude());
                    }
                    location.setAltitude(location.getAltitude() - f);
                }
            }

            location.setAltitude(location.getAltitude() - f);
            Log.v(TAG, "process: getAltitude()=" + location.getAltitude() + ", f=" + f + ",getAccuracy=" + location.getAccuracy());
        } else if (altitudeSource == 1) { //altitude from Pressure
            float altitudeFromPressure = SystemSensorManager.getInstance().getAltitudeFromPressure();

            if (locDataItem.count() < GPS_ALTITUDE_SAMPLE_MAX) {
                float gpsAltitude_offset = geoidHeightCalc.adjust(location.getLatitude(), location.getLongitude());
                float gpsAdjustedAltitude = (float)location.getAltitude() - gpsAltitude_offset;
                locDataItem.add(gpsAdjustedAltitude);
            }

            if (locDataItem.count() == GPS_ALTITUDE_SAMPLE_MAX) {
                altitude_offset = altitudeFromPressure - locDataItem.getAvg();
                locDataItem.countplus();
                Log.v(TAG, "process: altitude_offset=" + altitude_offset + ",avg item=" + locDataItem.getAvg());
            }
            location.setAltitude(altitudeFromPressure - altitude_offset);
        }
        location.setAltitude(location.getAltitude() + altitudeAdjustValue);
        Log.v(TAG, "process: after adjusted: " + location.getAltitude());
    }
}